package hotel.switchs.oversea.biz.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import hotel.base.oversea.constant.SwitchConstants;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;
import sun.misc.BASE64Encoder;

import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author lmf
 * @Date 2020/5/13 15:34
 **/
public class SwitchsHttpUtils {
    public static Logger logger= LoggerFactory.getLogger(SwitchsHttpUtils.class);

//    private static String access_token= HttpClientBaseAuth.getAuthToken();
    /**
     * 生成签名
     */
    public static String createSignature(){
        String tmp = String.valueOf(SwitchConstants.SUPPLIERID_TEST) + String.valueOf(System.currentTimeMillis()) + SwitchConstants.KEY_TEST;
        MessageDigest md5 = null;
        String signature="";
        try {
            md5 = MessageDigest.getInstance("MD5");
            BASE64Encoder base64en = new BASE64Encoder();
            signature = base64en.encode(md5.digest(tmp.getBytes("utf-8"))).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return signature;
    }

    /**
     * 发起接口请求
     */
    public static String sendRequest(Map<String,Object> map,String url,String profile){
        BaseRqeuestParam baseRqeuestParam=new BaseRqeuestParam();
        String result="";
        try{
            CloseableHttpClient client=null;
            CloseableHttpResponse response=null;
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, Object> data = new HashMap<>();
                data.put("requestor", baseRqeuestParam);
                data.putAll(map);
                int supplierID=profile.equals("test")?SwitchConstants.SUPPLIERID_TEST:SwitchConstants.SUPPLIERID_PROD;
                data.put("supplierID", supplierID);
                //获取 timestamp
                String timestamp = String.valueOf(System.currentTimeMillis());
                //计算 signature
                String key=profile.equals("test")?SwitchConstants.KEY_TEST:SwitchConstants.KEY_PROD;
                String tmp = String.valueOf(supplierID) + String.valueOf(System.currentTimeMillis()) + key;
                MessageDigest md5=MessageDigest.getInstance("MD5");
                BASE64Encoder base64en = new BASE64Encoder();
                String signature = base64en.encode(md5.digest(tmp.getBytes("utf-8"))).toUpperCase();
                //组装 http 请求数据
                String httpUrl=(profile.equals("test")?SwitchConstants.URL_TEST:SwitchConstants.URL_PROD)+url;
                HttpPost httpPost = new HttpPost(httpUrl);
                httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json");
                httpPost.setHeader("timestamp", timestamp);
                httpPost.setHeader("signature", signature);
                httpPost.setEntity(new StringEntity(objectMapper.writeValueAsString(data),
                        ContentType.create("text/json", "UTF-8")));
                client = HttpClients.createDefault();
                response = client.execute(httpPost);
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity);
                logger.info("请求的url是{}",httpUrl);
                logger.info("请求数据是{}",objectMapper.writeValueAsString(data));
                logger.info("返回数据是{}",result);
                if(result.contains("签名验证失败")){
                    Thread.sleep(200);
                    logger.info("==============接口签名验证失败，重试一次=====================");
                    timestamp = String.valueOf(System.currentTimeMillis());
                    tmp = String.valueOf(supplierID) + String.valueOf(System.currentTimeMillis()) + key;
                    signature = base64en.encode(md5.digest(tmp.getBytes("utf-8"))).toUpperCase();
                    httpPost = new HttpPost(httpUrl);
                    httpPost.setHeader(HTTP.CONTENT_TYPE, "application/json");
                    httpPost.setHeader("timestamp", timestamp);
                    httpPost.setHeader("signature", signature);
                    httpPost.setEntity(new StringEntity(objectMapper.writeValueAsString(data),
                            ContentType.create("text/json", "UTF-8")));
                    client = HttpClients.createDefault();
                    response = client.execute(httpPost);
                    entity = response.getEntity();
                    result = EntityUtils.toString(entity);
                    logger.info("请求的url是{}",httpUrl);
                    logger.info("接口签名验证失败,重试请求数据是{}",objectMapper.writeValueAsString(data));
                    logger.info("接口签名验证失败,重试返回数据是{}",result);
                }
            }finally {
                if (response != null) {
                    response.close();
                }
                if (client != null) {
                    client.close();
                }
            }
        }catch (Exception e ){
            e.printStackTrace();
            logger.info("===================请求接口发生异常======================");
        }

        //只针对是否存在resultStatus=null ；正常情况应不存在此字段内容，；20201118
        if(!ObjectUtils.isEmpty(result)){
            if(result.indexOf("resultStatus=null") != -1){
                result = result.replaceAll("resultStatus=null" ,"resultStatus={resultCode=-2, resultMsg=other-error}");
            }
        }
        return result;
    }

    public static void main(String[] arg){
        //date=2020-08-14, salePrice=13900, subPrice=695, subRatio=500, dayType=0
//        List<MtHotelOrderCheckPricesVo> priceModels = new ArrayList<>();
//        MtHotelOrderCheckPricesVo mtHotelOrderCheckPricesVo = new MtHotelOrderCheckPricesVo();
//        mtHotelOrderCheckPricesVo.setDate("2020-08-14");
//        mtHotelOrderCheckPricesVo.setSalePrice(13900);
//        mtHotelOrderCheckPricesVo.setSubPrice(695);
//        mtHotelOrderCheckPricesVo.setSubRatio(500);
//        mtHotelOrderCheckPricesVo.setDayType(0);
//        priceModels.add(mtHotelOrderCheckPricesVo);
//
//        MtHotelOrderCheckVo mtHotelOrderCheckVo = new MtHotelOrderCheckVo();
//        mtHotelOrderCheckVo.setCode(0);
//        mtHotelOrderCheckVo.setDesc(null);
//        mtHotelOrderCheckVo.setPriceModels(priceModels);
//
//        Result<Object> objectMeituanValidPriceResult = new Result<>();
//        objectMeituanValidPriceResult.setCode(200);
//        objectMeituanValidPriceResult.setMsg("success");
//        objectMeituanValidPriceResult.setData(mtHotelOrderCheckVo);
//        MtHotelOrderCheckVo mtHotelOrderCheckVoNew = (MtHotelOrderCheckVo) objectMeituanValidPriceResult.getData();
//
//        System.out.println("mtHotelOrderCheckVoNew==="+ JacksonUtil.objectToJson(mtHotelOrderCheckVoNew));

        String result = "{ResponseStatus={Timestamp=/Date(1605670482031+0800)/, Ack=Failure, Errors=[{Message=Execution is short-circuited by circuit-breaker. Command: soa.service.hotel.supplier.dlt.directly.v1.dltdirectlyservice.getdltordernotify Reason: Circuit-Breaker does not recovery from short-circuited. TimeoutThreshold: 20000 ms. HealthSnapshot: {TotalRequests = 2, ErrorCount = 2, FailureCount = 2, TimeoutCount = 0}., ErrorCode=SHORT_CIRCUITED, StackTrace=null, SeverityCode=Error, ErrorFields=null, ErrorClassification=SLAError}], Build=null, Version=null, Extension=[{Id=CLOGGING_TRACE_ID, Version=null, ContentType=null, Value=4929937839272593895}, {Id=RootMessageId, Version=null, ContentType=null, Value=921813-0a3c76bd-446019-1211001}]}, resultStatus=null, pagingType=null, dltOrderIds=null, newDltOrderIds=null, dltOrderList=null}";
        logger.info("result:{}",result);
        if(!ObjectUtils.isEmpty(result)){
            if(result.indexOf("resultStatus=null") != -1){
                result = result.replaceAll("resultStatus=null" ,"resultStatus={resultCode=-2, resultMsg=other-error}");
            }
        }

        logger.info("result222222:{}",result);
    }

}
